package com.quectel.cms.controller.scheduling;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.scheduling.SchedulingLeaveBusiness;
import com.quectel.business.common.util.sys.SysCodeUtils;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.ex.scheduling.SchedulingLeaveException;
import com.quectel.cms.util.SessionHolder;
import com.quectel.cms.vo.scheduling.SchedulingLeaveBalanceRep;
import com.quectel.constant.core.scheduling.SchedulingLeaveConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.constant.sys.SysCodeKeyConstants;
import com.quectel.core.module.dept.dto.DeptDto;
import com.quectel.core.module.dept.dto.DeptPersonDto;
import com.quectel.core.module.dept.service.DeptPersonService;
import com.quectel.core.module.dept.service.DeptService;
import com.quectel.core.module.scheduling.dto.SchedulingLeaveBalanceDto;
import com.quectel.core.module.scheduling.dto.SchedulingLeaveConfigDto;
import com.quectel.core.module.scheduling.dto.SchedulingLeavePersonBindingDto;
import com.quectel.core.module.scheduling.service.SchedulingLeaveBalanceService;
import com.quectel.core.module.scheduling.service.SchedulingLeaveConfigService;
import com.quectel.core.module.scheduling.service.SchedulingLeavePersonBindingService;
import com.quectel.core.module.schedulingapply.dto.vo.SchedulingTimeVO;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.util.common.*;
import com.quectel.util.kit.PageFetchKit;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangheng
 * @email nolan.zhang@quectel.com
 * @date 2023/07/05 13:24
 */
@RestController
@RequestMapping("schedulingLeaveBalance")
@Tag(name = "SchedulingLeaveBalanceController", description = "考勤假期余额相关api")
public class SchedulingLeaveBalanceController extends BaseController {

    @DubboReference
    private SchedulingLeaveBalanceService schedulingLeaveBalanceService;
    @DubboReference
    private DeptPersonService deptPersonService;
    @DubboReference
    private SchedulingLeaveConfigService schedulingLeaveConfigService;
    @DubboReference
    private SchedulingLeavePersonBindingService schedulingLeavePersonBindingService;
    @DubboReference
    private DeptService deptService;
    @DubboReference
    private VillageService villageService;

    @Autowired
    private SchedulingLeaveBusiness schedulingLeaveBusiness;


    @PostMapping("importExcel")
    @RequirePermissions(values = "schedulingLeaveBalance:importExcel")
    @Operation(summary = "假期余额数据导入")
    public Response<Object> importExcel(
            MultipartHttpServletRequest request
    ) {
        final Long tenantId = SessionHolder.getSysUser().getTenantId();
        int totalCount = 0;
        int successCount = 0;

        List<SchedulingLeaveBalanceDto> schedulingLeaveBalanceDtos = new ArrayList<>();
        Iterator<String> fileNames = request.getFileNames();
        while (fileNames.hasNext()) {
            String next = fileNames.next();
            List<MultipartFile> files = request.getFiles(next);
            for (MultipartFile file : files) {
                try {
                    List<Map<Integer, String>> analysis = POIUtils.analysis(file.getInputStream(), 1, 0);
                    totalCount += analysis.size();

                    for (Map<Integer, String> integerStringMap : analysis) {
                        //第0个是小区
                        String villageName = integerStringMap.get(0);
                        VillageDto villageDto = villageService.selectCacheByName(tenantId, villageName);
                        if (villageDto == null) {
                            continue;
                        }
                        //第2个是工号
                        //第3个是手机号
                        Map<String, Object> deptPersonParams = new HashMap<>();
                        deptPersonParams.put(LambdaUtil.getFieldName(DeptPersonDto::getTenantId), tenantId);
                        deptPersonParams.put(LambdaUtil.getFieldName(DeptPersonDto::getVillageId), villageDto.getId());
                        deptPersonParams.put(LambdaUtil.getFieldName(DeptPersonDto::getJobNo), integerStringMap.get(2));
                        deptPersonParams.put(LambdaUtil.getFieldName(DeptPersonDto::getMobile), integerStringMap.get(3));
                        List<DeptPersonDto> deptPersonDtos = deptPersonService.queryList(deptPersonParams);
                        if (CollectionUtils.isEmpty(deptPersonDtos)) {
                            continue;
                        }
                        DeptPersonDto deptPersonDto = deptPersonDtos.get(0);
                        //第9个是假期id
                        String leaveIdStr = integerStringMap.get(9);
                        SchedulingLeaveConfigDto schedulingLeaveConfigDto = schedulingLeaveConfigService.selectById(Long.valueOf(leaveIdStr));
                        if (schedulingLeaveConfigDto == null) {
                            continue;
                        }
                        //第10个是发放数量
                        String balance = integerStringMap.get(10);
                        if (StringUtils.isEmpty(balance)) {
                            continue;
                        }
                        SchedulingLeavePersonBindingDto schedulingLeavePersonBindingDto = schedulingLeavePersonBindingService.selectByLeaveAndPerson(schedulingLeaveConfigDto.getId(), deptPersonDto.getId());
                        if (schedulingLeavePersonBindingDto == null) {
                            continue;
                        }

                        //第11个是开始日期
                        String startTimeStr = integerStringMap.get(11);
                        //第12个是结束日期
                        String endTimeStr = integerStringMap.get(12);
                        //第12个是结束日期
                        String effectiveEndTimeStr = integerStringMap.get(13);

                        Date startTime = DateUtils.parse(startTimeStr, DateUtils.FormatType.COMMON);
                        Date endTime = DateUtils.parse(endTimeStr, DateUtils.FormatType.COMMON);
                        Date effectiveEndTime = DateUtils.parse(effectiveEndTimeStr, DateUtils.FormatType.COMMON);
                        if (DateUtil.year(startTime) != DateUtil.year(endTime)) {
                            continue;
                        }

                        SchedulingLeaveBalanceDto dto = null;
                        //查询确切日期的记录
                        Map<String, Object> balanceParams = new HashMap<>();
                        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getLeaveId), schedulingLeaveConfigDto.getId());
                        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getPersonId), deptPersonDto.getId());
                        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getYear), DateUtil.year(startTime));
                        balanceParams.put(SchedulingLeaveConstants.EXACT_START_TIME, startTimeStr);
                        balanceParams.put(SchedulingLeaveConstants.EXACT_END_TIME, endTimeStr);
                        List<SchedulingLeaveBalanceDto> exactBalance = schedulingLeaveBalanceService.queryList(balanceParams);
                        if (CollectionUtils.isNotEmpty(exactBalance)) {
                            dto = exactBalance.get(0);
                            BigDecimal multiply = dto.getBalance().add(new BigDecimal(balance).setScale(SchedulingLeaveConstants.DEFAULT_SCALE, RoundingMode.HALF_UP));
                            dto.setBalance(multiply);
                        } else {
                            //根据开始日期和结束日期查询 如果有交叉的 则查询出来对应的数据的第一条 将余额新增或者扣减
                            List<SchedulingLeaveBalanceDto> timeCrossedRecord = getTimeCrossedRecord(schedulingLeaveConfigDto.getId(), deptPersonDto.getId(), DateUtil.year(startTime), startTimeStr, endTimeStr);
                            if (CollectionUtils.isNotEmpty(timeCrossedRecord)) {
                                dto = timeCrossedRecord.get(0);
                                BigDecimal multiply = dto.getBalance().add(new BigDecimal(balance).setScale(SchedulingLeaveConstants.DEFAULT_SCALE, RoundingMode.HALF_UP));
                                dto.setBalance(multiply);
                            } else {
                                //如果没有查询到交叉记录则新增一条记录
                                dto = new SchedulingLeaveBalanceDto();
                                dto.setLeaveId(schedulingLeaveConfigDto.getId());
                                dto.setPersonId(deptPersonDto.getId());
                                dto.setBalance(new BigDecimal(balance).setScale(SchedulingLeaveConstants.DEFAULT_SCALE, RoundingMode.HALF_UP));
                                dto.setUnit(schedulingLeaveConfigDto.getMinUnit());
                                dto.setYear(DateUtil.year(startTime));
                                dto.setStartTime(startTime);
                                dto.setEndTime(endTime);
                                dto.setEffectiveStartTime(startTime);
                                dto.setEffectiveEndTime(effectiveEndTime);
                                dto.setCreateTime(new Date());
                            }
                        }
                        schedulingLeaveBalanceDtos.add(dto);
                    }


                } catch (Exception e) {
                    logger.error("解析车辆出入数据出错", e);
                }
            }
        }
        schedulingLeaveBalanceService.saveOrUpdateBatch(schedulingLeaveBalanceDtos);
        successCount = schedulingLeaveBalanceDtos.size();
        return Response.error("导入数据完成 总数:" + totalCount + " 成功数:" + successCount);
    }


    /**
     * 下载模板 schedulingLeaveBalance:exportExcel
     */
    @GetMapping("downloadTemplate")
    @RequirePermissions(values = "schedulingLeaveBalance:exportExcel")
    @Operation(summary = "导出假期余额记录用于批量发放余额")
    public void downloadTemplate(
            @Parameter(description = "小区id") @RequestParam Long villageId,
            @Parameter(description = "假期id") @RequestParam("leaveId") Long leaveId,
            @Parameter(description = "人员列表") @RequestParam("personList") List<Long> personList,
            HttpServletResponse hresp) {

        if (CollectionUtils.isEmpty(personList)) {
            throw new SchedulingLeaveException("人员列表为空");
        }
        SchedulingLeaveConfigDto schedulingLeaveConfigDto = schedulingLeaveConfigService.selectById(leaveId);
        if (schedulingLeaveConfigDto == null) {
            throw new SchedulingLeaveException("假期不存在");
        }

        List<DeptPersonDto> deptPersonDtos = new ArrayList<>();
        for (Long l : personList) {
            SchedulingLeavePersonBindingDto schedulingLeavePersonBindingDto = schedulingLeavePersonBindingService.selectByLeaveAndPerson(leaveId, l);
            if (schedulingLeavePersonBindingDto != null) {
                DeptPersonDto deptPersonDto = deptPersonService.selectCacheById(l);
                if (deptPersonDto != null && deptPersonDto.getVillageId().equals(villageId) && deptPersonDto.getTenantId().equals(SessionHolder.getSysUser().getTenantId())) {
                    deptPersonDtos.add(deptPersonDto);
                }
            }
        }


        String[] headers = new String[]{"所属小区", "姓名", "工号", "手机号", "性别", "部门", "入职日期", "首次参加工作日期", "假期类型", "假期唯一标识", "发放数量（1位小数，多余位小数自动四舍五入）", "适用周期开始日期（yyyy-MM-dd HH:mm:ss）", "适用周期结束日期（yyyy-MM-dd HH:mm:ss）","有效周期结束日期（yyyy-MM-dd HH:mm:ss）"};
        List<String[]> dataList = new ArrayList<>();
        for (DeptPersonDto data : deptPersonDtos) {
            String[] item = new String[headers.length];
            item[0] = data.getVillageName();
            item[1] = data.getName();
            item[2] = data.getJobNo();
            item[3] = data.getMobile();
            item[4] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.GENDER, data.getGender() + "");
            item[5] = data.getDept() != null ? data.getDept().getName() : "";
            item[6] = DateUtils.format(data.getJoinedDate(), DateUtils.FormatType.SIMPLE);
            item[7] = DateUtils.format(data.getFirstJobDate(), DateUtils.FormatType.SIMPLE);
            item[8] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.SCHEDULING_LEAVE_TYPE, schedulingLeaveConfigDto.getType() + "");
            item[9] = schedulingLeaveConfigDto.getId() + "";
            item[10] = "";
            item[11] = "";
            item[12] = "";
            item[13] = "";
            dataList.add(item);
        }
        POIUtils.exportExcel(hresp, "假期余额发放", headers, dataList, "假期余额发放模板");
    }

    /**
     * 导出记录 schedulingLeaveBalance:exportExcel
     */
    @GetMapping("exportExcel")
    @RequirePermissions(values = "schedulingLeaveBalance:exportExcel")
    @Operation(summary = "导出假期余额记录用于批量发放余额")
    public void exportExcel(
            @RequestParam Map<String, Object> params,
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "部门id") @RequestParam(required = false) Long deptId,
            HttpServletResponse hresp) {

        Request request = Request.configParamsNotPage(params);

        super.fillAuthorityData(request.getParams());
        if (villageId == null && deptId == null) {
            throw new SchedulingLeaveException("小区id和部门id都为空");
        }
        if (deptId != null) {
            DeptDto deptDto = deptService.selectCacheById(deptId);
            if (deptDto == null) {
                throw new SchedulingLeaveException("部门不存在");
            } else {
                villageId = deptDto.getVillageId();
            }
        }

        request.put(LambdaUtil.getFieldName(DeptPersonDto::getTenantId), SessionHolder.getSysUser().getTenantId());
        if (villageId != null) {
            request.put(LambdaUtil.getFieldName(DeptPersonDto::getVillageId), villageId);
        } else {
            request.put(LambdaUtil.getFieldName(DeptPersonDto::getVillageId), villageId);
            request.put(LambdaUtil.getFieldName(DeptPersonDto::getDeptId), deptId);
        }

        List<DeptPersonDto> list = PageFetchKit.fetchAll(req -> deptPersonService.queryList(req), params, 500);
        String[] strings = {"所属小区", "工号", "手机号", "性别", "部门", "入职日期", "首次参加工作日期"};
        List<String> headers = new ArrayList<>(Arrays.asList(strings));

        List<SchedulingLeaveConfigDto> schedulingLeaveConfigDtos = schedulingLeaveBusiness.getSchedulingLeaveBalanceRep(SessionHolder.getSysUser().getTenantId(), villageId);

        List<SchedulingLeaveBalanceRep> result = null;
        if (CollectionUtils.isNotEmpty(schedulingLeaveConfigDtos)) {
            if (CollectionUtils.isNotEmpty(schedulingLeaveConfigDtos)) {
                result = list.stream().map(deptPersonDto -> getSchedulingLeaveBalanceRep(deptPersonDto, schedulingLeaveConfigDtos)).collect(Collectors.toList());
            } else {
                result = list.stream().map(deptPersonDto -> {
                    SchedulingLeaveBalanceRep schedulingLeaveBalanceRep = new SchedulingLeaveBalanceRep();
                    schedulingLeaveBalanceRep.setDeptPerson(deptPersonDto);
                    return schedulingLeaveBalanceRep;
                }).collect(Collectors.toList());
            }
        } else {
            result = new ArrayList<>();
        }
        for (SchedulingLeaveConfigDto schedulingLeaveConfigDto : schedulingLeaveConfigDtos) {
            headers.add(SysCodeUtils.easyToGetName(SysCodeKeyConstants.SCHEDULING_LEAVE_TYPE, schedulingLeaveConfigDto.getType() + ""));
        }

        List<String[]> dataList = new ArrayList<>();
        for (SchedulingLeaveBalanceRep data : result) {
            List<String> item = new ArrayList<>();
            //所属小区
            item.add(data.getDeptPerson() != null ? data.getDeptPerson().getVillageName() : "");
            //工号
            item.add(data.getDeptPerson() != null ? data.getDeptPerson().getJobNo() : "");
            //手机号
            item.add(data.getDeptPerson() != null ? data.getDeptPerson().getMobile() : "");
            //性别
            item.add(data.getDeptPerson() != null ? SysCodeUtils.easyToGetName(SysCodeKeyConstants.GENDER, data.getDeptPerson().getGender() + "") : "");
            //部门
            item.add(data.getDeptPerson() != null && data.getDeptPerson().getDept() != null ? data.getDeptPerson().getDept().getName() : "");
            //入职日期
            item.add(data.getDeptPerson() != null && data.getDeptPerson().getJoinedDate() != null ? DateUtils.format(data.getDeptPerson().getJoinedDate(), DateUtils.FormatType.SIMPLE) : "");
            //首次参加工作日期
            item.add(data.getDeptPerson() != null && data.getDeptPerson().getFirstJobDate() != null ? DateUtils.format(data.getDeptPerson().getFirstJobDate(), DateUtils.FormatType.SIMPLE) : "");
            if (CollectionUtils.isNotEmpty(schedulingLeaveConfigDtos)) {
                for (SchedulingLeaveConfigDto schedulingLeaveConfigDto : schedulingLeaveConfigDtos) {
                    if (data.getLeaveBalanceList() == null) {
                        item.add("0");
                    } else {
                        SchedulingLeaveBalanceRep.LeaveBalance leaveBalance = data.getLeaveBalanceList().stream().filter(balance -> balance.getLeaveId().equals(schedulingLeaveConfigDto.getId())).findFirst().orElse(null);
                        if (leaveBalance != null) {
                            item.add(leaveBalance.getRestBalance().setScale(1, RoundingMode.HALF_UP) + SysCodeUtils.easyToGetName(SysCodeKeyConstants.SCHEDULING_LEAVE_TIME_UNIT, leaveBalance.getUnit() + ""));
                        } else {
                            item.add("0");
                        }
                    }
                }
            }
            dataList.add(item.toArray(new String[]{}));
        }
        POIUtils.exportExcel(hresp, "假期余额记录", headers.toArray(new String[]{}), dataList, "假期余额记录");
    }


    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("listPerson")
    @RequirePermissions(values = "schedulingLeaveBalance:list")
    @Operation(summary = "分页获取考勤假期余额列表")
    public Response<Page<SchedulingLeaveBalanceRep>> listPerson(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize,
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "部门id") @RequestParam(required = false) Long deptId
    ) {

        if (villageId == null && deptId == null) {
            return Response.<Page<SchedulingLeaveBalanceRep>>ok().wrap(Page.empty(pageNo, pageSize));
        }
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        request.put(LambdaUtil.getFieldName(DeptPersonDto::getTenantId), SessionHolder.getSysUser().getTenantId());
        request.put(LambdaUtil.getFieldName(DeptPersonDto::getVillageId), villageId);
        request.put(LambdaUtil.getFieldName(DeptPersonDto::getDept), deptId);
        int total = deptPersonService.queryTotal(request.getParams());

        List<SchedulingLeaveBalanceRep> list = null;
        if (total > 0) {
            List<DeptPersonDto> deptPersonDtos = deptPersonService.queryList(request.getParams());
            List<SchedulingLeaveConfigDto> schedulingLeaveConfigDtos = schedulingLeaveBusiness.getSchedulingLeaveBalanceRep(SessionHolder.getSysUser().getTenantId(), villageId);
            if (CollectionUtils.isNotEmpty(schedulingLeaveConfigDtos)) {
                list = deptPersonDtos.stream().map(deptPersonDto -> getSchedulingLeaveBalanceRep(deptPersonDto, schedulingLeaveConfigDtos)).collect(Collectors.toList());
            } else {
                list = new ArrayList<>();
            }
        } else {
            list = new ArrayList<>();
        }

        Page<SchedulingLeaveBalanceRep> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<SchedulingLeaveBalanceRep>>ok().wrap(page);
    }


    /**
     * 获取员工假期详情
     *
     * @param deptPersonDto             员工
     * @param schedulingLeaveConfigDtos 限额假期列表
     * @return
     */
    private SchedulingLeaveBalanceRep getSchedulingLeaveBalanceRep(DeptPersonDto deptPersonDto, List<SchedulingLeaveConfigDto> schedulingLeaveConfigDtos) {
        SchedulingLeaveBalanceRep schedulingLeaveBalanceRep = new SchedulingLeaveBalanceRep();
        schedulingLeaveBalanceRep.setDeptPerson(deptPersonDto);

        List<SchedulingLeaveBalanceRep.LeaveBalance> leaveBalanceList = null;
        if (CollectionUtils.isNotEmpty(schedulingLeaveConfigDtos)) {
            leaveBalanceList = schedulingLeaveConfigDtos.stream().map(schedulingLeaveConfigDto -> getSchedulingLeaveBalanceRep(deptPersonDto, schedulingLeaveConfigDto)).collect(Collectors.toList());
        } else {
            leaveBalanceList = new ArrayList<>();
        }
        schedulingLeaveBalanceRep.setLeaveBalanceList(leaveBalanceList);

        return schedulingLeaveBalanceRep;

    }

    /**
     * 获取员工假期余额,包装为SchedulingLeaveBalanceRep.LeaveBalance
     *
     * @param deptPersonDto            员工dto
     * @param schedulingLeaveConfigDto 限额假期dto
     * @return
     */
    private SchedulingLeaveBalanceRep.LeaveBalance getSchedulingLeaveBalanceRep(DeptPersonDto deptPersonDto, SchedulingLeaveConfigDto schedulingLeaveConfigDto) {
        SchedulingLeaveBalanceRep.LeaveBalance leaveBalance = new SchedulingLeaveBalanceRep.LeaveBalance();
        leaveBalance.setLeaveId(schedulingLeaveConfigDto.getId());
        leaveBalance.setLeaveType(schedulingLeaveConfigDto.getType());

        String now = DateUtils.format(new Date(), DateUtils.FormatType.COMMON);
        Response<SchedulingTimeVO> leaveBalanceResult = schedulingLeaveBusiness.getLeaveBalance(schedulingLeaveConfigDto.getId(), deptPersonDto.getId(), now, null);
        if (!leaveBalanceResult.isSuccess()) {
            leaveBalance.setUnit(schedulingLeaveConfigDto.getMinUnit());
            leaveBalance.setRestBalance(BigDecimal.ZERO);
            return leaveBalance;
        }

        SchedulingTimeVO data = leaveBalanceResult.getData();
        leaveBalance.setUnit(data.getTimeUnit());
        leaveBalance.setRestBalance(data.getTimeLength());
        return leaveBalance;

    }


    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @RequirePermissions(values = "schedulingLeaveBalance:list")
    @Operation(summary = "分页获取考勤假期余额列表")
    public Response<Page<SchedulingLeaveBalanceDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = schedulingLeaveBalanceService.queryTotal(request.getParams());

        List<SchedulingLeaveBalanceDto> list = null;
        if (total > 0) {
            list = schedulingLeaveBalanceService.queryList(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        Page<SchedulingLeaveBalanceDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<SchedulingLeaveBalanceDto>>ok().wrap(page);
    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "schedulingLeaveBalance:edit")
    @Operation(summary = "在编辑时根据id查询考勤假期余额详情")
    public Response<SchedulingLeaveBalanceDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (schedulingLeaveBalanceService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        SchedulingLeaveBalanceDto schedulingLeaveBalanceDto = schedulingLeaveBalanceService.selectById(id);
        if (schedulingLeaveBalanceDto != null) {
            DeptPersonDto deptPersonDto = deptPersonService.selectCacheById(schedulingLeaveBalanceDto.getPersonId());
            schedulingLeaveBalanceDto.setDeptPerson(deptPersonDto);
        }

        return Response.<SchedulingLeaveBalanceDto>ok().wrap(schedulingLeaveBalanceDto);
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "schedulingLeaveBalance:info")
    @Operation(summary = "根据id查询考勤假期余额的详情")
    public Response<SchedulingLeaveBalanceDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (schedulingLeaveBalanceService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        SchedulingLeaveBalanceDto schedulingLeaveBalanceDto = schedulingLeaveBalanceService.selectById(id);

        return Response.<SchedulingLeaveBalanceDto>ok().wrap(schedulingLeaveBalanceDto);
    }

    /**
     * 保存
     *
     * @param schedulingLeaveBalanceDto
     * @return
     */
    @PostMapping("save")
    @RequirePermissions(values = "schedulingLeaveBalance:edit")
    @Operation(summary = "新增考勤假期余额")
    public Response<Object> save(@RequestBody @Validated SchedulingLeaveBalanceDto schedulingLeaveBalanceDto) {
        SchedulingLeaveConfigDto schedulingLeaveConfigDto = schedulingLeaveConfigService.selectCacheById(schedulingLeaveBalanceDto.getLeaveId());
        Response response = schedulingLeaveBusiness.checkLeaveConfig(schedulingLeaveConfigDto);
        if (!response.isSuccess()) {
            return Response.error(response.getMessage());
        }

        int startYear = DateUtil.year(schedulingLeaveBalanceDto.getStartTime());
        int endYear = DateUtil.year(schedulingLeaveBalanceDto.getStartTime());
        if (!schedulingLeaveBalanceDto.getYear().equals(startYear) || !schedulingLeaveBalanceDto.getYear().equals(endYear)) {
            return Response.error("开始时间和结束时间必须和年份一致");
        }

        if (schedulingLeaveBusiness.isTimeCrossed(schedulingLeaveBalanceDto.getLeaveId()
                , schedulingLeaveBalanceDto.getPersonId()
                , schedulingLeaveBalanceDto.getYear()
                , DateUtils.format(schedulingLeaveBalanceDto.getStartTime(), DateUtils.FormatType.COMMON)
                , DateUtils.format(schedulingLeaveBalanceDto.getEndTime(), DateUtils.FormatType.COMMON))) {
            return Response.error("与其他余额时间段冲突，请检查开始时间和结束时间");
        }

        //填充基础数据
        fillSaveCommonData(schedulingLeaveBalanceDto);
        schedulingLeaveBalanceDto.setEffectiveStartTime(schedulingLeaveBalanceDto.getStartTime());
        schedulingLeaveBalanceDto.setUnit(schedulingLeaveConfigDto.getMinUnit());
        schedulingLeaveBalanceDto.setCreateTime(new Date());
        schedulingLeaveBalanceService.save(schedulingLeaveBalanceDto);

        return Response.ok();
    }



    /**
     * 获得时间交叉的记录
     *
     * @param leaveId   假期id
     * @param personId  员工id
     * @param year      年份
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 如果交叉返回true 否则返回false
     */
    private List<SchedulingLeaveBalanceDto> getTimeCrossedRecord(Long leaveId, Long personId, Integer year, String startTime, String endTime) {
        //查询同一时期是否有其他生效的余额
        Map<String, Object> balanceParams = new HashMap<>();
        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getLeaveId), leaveId);
        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getPersonId), personId);
        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getYear), year);
        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getStartTime), startTime);
        balanceParams.put(LambdaUtil.getFieldName(SchedulingLeaveBalanceDto::getEndTime), endTime);
        balanceParams.put(SchedulingLeaveConstants.IS_TIME_CROSSED, SystemConstants.YES);
        return schedulingLeaveBalanceService.queryList(balanceParams);
    }

    /**
     * 修改
     *
     * @param schedulingLeaveBalanceDto
     * @return
     */
    @PostMapping("update")
    @RequirePermissions(values = "schedulingLeaveBalance:edit")
    @Operation(summary = "根据id修改考勤假期余额")
    public Response<Object> update(@RequestBody @Validated SchedulingLeaveBalanceDto schedulingLeaveBalanceDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(schedulingLeaveBalanceDto.getId()));
        if (schedulingLeaveBalanceService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //填充基础数据
        fillEditCommonData(schedulingLeaveBalanceDto);

        schedulingLeaveBalanceService.updateById(schedulingLeaveBalanceDto);

        return Response.ok();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("delete")
    @RequirePermissions(values = "schedulingLeaveBalance:delete")
    @Operation(summary = "根据多条记录id批量删除考勤假期余额")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {

            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (schedulingLeaveBalanceService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }
        }

        schedulingLeaveBalanceService.deleteBatch(ids);

        return Response.ok();
    }
}
